/* Copyright (c) 2004-2008, Andriy Nikolov
 * All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.processmining.email;

import java.util.*;
import java.awt.*;

/**
 * <p>A panel to show the task-person diagram in the standalone version</p>
 *
 * @author Andriy Nikolov
 * @version 1.0
 */
public class TaskPersonTablePanel
    extends DiagramPanel {
  TaskPersonTable table;
  Hashtable taskNodesTable, personNodesTable;
  Vector taskNodes, personNodes;

  public TaskPersonTablePanel() {
    super();
    taskNodes = new Vector();
    personNodes = new Vector();
    taskNodesTable = new Hashtable();
    personNodesTable = new Hashtable();
  }

  public void setTable(TaskPersonTable table) {
    this.table = table;
    createNodes();
    createArcs();
  }

  public TaskPersonTable getTable() {
    return table;
  }


  public void calculateSize() {
    int numberOfNodes;
    int height;
    Dimension size;
    maxNumberOfNodes = Math.max(taskNodes.size(), personNodes.size());

    height = DIAGRAM_TOPMOST_POINT*scale;
    height+=(DiagramNode.NODE_HEIGHT+DiagramNode.NODE_MIN_INTERVAL)*scale*maxNumberOfNodes;
    size = new Dimension(this.getWidth(), height);
    setSize(size);
    setPreferredSize(size);
    setMinimumSize(size);
  }

  private void createNodes() {
      Vector taskTypes, personList;
      PersonNode curPersonNode;
      TaskNode curTaskNode;
      String curName;
      int i;

      taskTypes = table.getTaskList();
      for(i=0;i<taskTypes.size();i++) {
        curName = (String)taskTypes.get(i);
        curTaskNode = new TaskNode(curName, this);
        taskNodesTable.put(curName, curTaskNode);
        taskNodes.add(curTaskNode);
      }

      personList = table.getPersonList();
      for(i=0;i<personList.size();i++) {
        curName = (String)personList.get(i);
        if(table.isPersonConnected(curName)) {
          curPersonNode = new PersonNode(curName, this);
          personNodesTable.put(curName, curPersonNode);
          personNodes.add(curPersonNode);
        }
      }

      calculateSize();
      DiagramNode curNode;
      Point nodeCenter;

      for(i=0;i<taskNodes.size();i++) {
        curNode = (DiagramNode)taskNodes.get(i);
        nodeCenter = calculateNodeCenter(i, taskNodes.size(), true);
        curNode.setCenter(nodeCenter);
        add(curNode, null);
      }

      for(i=0;i<personNodes.size();i++) {
        curNode = (DiagramNode)personNodes.get(i);
        nodeCenter = calculateNodeCenter(i, personNodes.size(), false);
        curNode.setCenter(nodeCenter);
        add(curNode, null);
      }

  /*    Node curNode;
      Point nodeCenter;
      EMailRecipient tmp;

      LinkedList emplList = sociogram.getEmployeesList();
      for(int i=0;i<emplList.size();i++) {
        tmp = (EMailRecipient)emplList.get(i);
        curNode = new Node(tmp.getName(), this);
        nodeCenter = calculateNodeCenter(i, emplList.size());
        curNode.setCenter(nodeCenter);
        nodes.add(curNode);
        add(curNode, null);
      }*/
  }

  private Point calculateNodeCenter(int cur, int total, boolean isTask) {
    double cx, cy;
    double interval;
    if(isTask) {
      cx = this.getWidth()/4;
    } else {
      cx = 3*this.getWidth()/4;
    }
    interval = (DiagramNode.NODE_HEIGHT+DiagramNode.NODE_MIN_INTERVAL)*DiagramNode.scale*(((double)(maxNumberOfNodes))/((double)(total)));
    cy = DIAGRAM_TOPMOST_POINT+cur*interval;
    return new Point(new Double(cx).intValue(), new Double(cy).intValue());
  }

  private void createArcs() {
    double weight;
    DiagramArc curArc;
    int i, j;
    double max;
    arcs.clear();
    TaskNode taskNode;
    PersonNode personNode;

    for (j=0;j<personNodes.size();j++) {
      personNode = (PersonNode)personNodes.get(j);
      max = 0;
      if(showOnlyMaximalArcs) {
        // find the task, to which the person is mostly connected
        for (i=0;i<taskNodes.size();i++) {
          taskNode = (TaskNode) taskNodes.get(i);
          weight = table.getNormalizedWeight(taskNode.getText(), personNode.getText());
          if(weight>max) {
            max = weight;
          }
        }
      }
      for (i=0;i<taskNodes.size();i++) {
        taskNode = (TaskNode)taskNodes.get(i);
        weight = table.getNormalizedWeight(taskNode.getText(), personNode.getText());
        if(weight>0) {
          if(showOnlyMaximalArcs) {
            if(weight<max) {
              continue;
            }
          }
          curArc = new DiagramArc();
          curArc.setWeight(weight);
          curArc.setFrom(taskNode);
          curArc.setTo(personNode);
          arcs.add(curArc);
        }
      }
    }
  }
}
